# -*- coding: UTF-8 -*-
from mutator import blobmuta
from mutator import stringmuta
from mutator import binarymuta
import random
import bluetooth


class Bnep:

    '''
    BNEP Packet Type
    BNEP_GENERAL_ETHERNET   00
    BNEP_CONTROL    01
    BNEP_COMPRESSED_ETHERNET    02
    BNEP_COMPRESSED_ETHERNET_SOURCE_ONLY    03
    BNEP_COMPRESSED_ETHERNET_DEST_ONLY  04
    Reserved for future use 05-7E
    Reserved for 802.2 LLC Packets for IEEE 802.15.1 WG 7F
    '''

    BNEP_TYPE = ['\x00', '\x01', '\x02', '\x03', '\x04']
    EXTENSION = ['\x00', '\x01'] # 组合时放在BNEP_TYPE之前！！！
    # extension = 0x00 后面的playload放在整个报文后

    BNEP_TYPE_EXTENSION = ['\x80', '\x81', '\x82', '\x83', '\x84']

    # BNEP_TYPE=0x00 BNEP_GENERAL_ETHERNET
    DESTINATION_ADDRESS = ['\x00\x01\x02\x03\x04\x05'] # 48bit
    SOURCE_ADDRESS = ['\x00\x01\x02\x03\x04\x05'] # 48bit
    NETWORK_PROTOCOL_TYPE = ['\x00\x01'] #16bit
    # next...Extension Header or Payload
    EH_OR_PL = []

    # -----------------------------------------------------------------------------------------------
    # BNEP_TYPE=0x01 BNEP_ CONTROL
    '''
    BNEP Control Type
    BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD 00
    BNEP_SETUP_CONNECTION_REQUEST_MSG 01
    BNEP_SETUP_CONNECTION_RESPONSE_MSG 02
    BNEP_FILTER_NET_TYPE_SET_MSG 03
    BNEP_FILTER_NET_TYPE_RESPONSE_MSG 04
    BNEP_FILTER_MULTI_ADDR_SET_MSG 05
    BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG 06
    Reserved for future use 07-FF
    '''
    BNEP_CONTROL_TYPE = ['\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06'] # 8bit,0x00-0xFF

    # BNEP_CONTROL_TYPE = 0x00 BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD
    UNKONWN_CONTROL_TYPE = []

    # BNEP_CONTROL_TYPE = 0x01 BNEP_SETUP_CONNECTION_REQUEST_MSG
    UUID_SIZE = [] # 8bit identifies the length of one of the SDP service UUID
    DESTINATION_SERVICE_UUID = [] # 2-16bytes
    SOURCE_SERVICE_UUID = [] # 2-16bytes

    # BNEP_CONTROL_TYPE = 0x02 BNEP_SETUP_CONNECTION_RESPONSE_MSG
    '''
    Response Messages
    Operation Successful    0x0000
    Operation Failed: Invalid Destination Service UUID (the
    UUID is not a service UUID defined by the profile which is
    using BNEP) 0x0001
    Operation Failed: Invalid Source Service UUID (the UUID is
    not a service UUID defined by the profile which is using
    BNEP)   0x0002
    Operation Failed: Invalid Service UUID Size 0x0003
    Operation Failed: Connection not allowed    0x0004
    Reserved for future use 0x0005-0xFFFF
    '''
    SETUP_CONNECTION_RESPONSE_MESSAGE = ['\x00\x00', '\x00\x01', '\x00\x02', '\x00\x03', '\x00\x04'] # 16bits

    # BNEP_CONTROL_TYPE = 0x03 BNEP_FILTER_ NET_TYPE_SET_MSG
    FILTER_NET_TYPE_SET_MSG_LIST_LENGTH = []
    NETWORK_PROTOCOL_TYPE_START = [] # 16bits
    NETWORK_PROTOCOL_TYPE_END = [] # 16bits

    # BNEP_CONTROL_TYPE = 0x04 BNEP_FILTER_ NET_TYPE_RESPONSE_MSG
    '''
    Response Messages
    Operation Successful    0x0000
    Unsupported Request 0x0001
    Operation Failed: Invalid Networking Protocol Type Range 
    (A Networking Protocol Type Start value is greater than its 
    corresponding Networking Protocol Type End value)   0x0002
    Operation Failed: Too many filters  0x0003
    Operation Failed: Unable to fulfill request due to security
    reasons.    0x0004
    Reserved for future use 0   0x0005-0xFFFF
    '''
    FILTER_NET_TYPE_RESPONSE_MESSAGE = ['\x00\x00', '\x00\x01', '\x00\x02', '\x00\x03', '\x00\x04'] # 16bits

    # BNEP_CONTROL_TYPE = 0x05 BNEP_FILTER_MULTI_ADDR_SET_MSG
    FILTER_MULTI_ADDR_SET_MSG_LIST_LENGTH = []
    MULTICAST_ADDRESS_START = [] # 48bits
    MULTICAST_ADDRESS_END = [] # 48bits

    # BNEP_CONTROL_TYPE = 0x06 BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG
    '''
    Operation Successful 0x0000
    Unsupported Request 0x0001
    Operation Failed: Invalid multicast address (A Multicast   
    Address Start is greater than the corresponding
    Multicast Address End)  0x0002
    Operation Failed: Too many filters. 0x0003
    Operation Failed: Unable to fulfill request due to security
    reasons.    0x0004
    Reserved for future use 0x0005-0xFFFF
    '''
    FILTER_MULTI_ADDR_RESPONSE_MESSAGE = [] # 16bits
    # --------------------------------------------------------------------------------------------------------

    # BNEP_TYPE=0x02 BNEP_COMPRESSED_ETHERNET
    NETWORKING_PROTOCOL_TYPE = [] # 16bits

    # --------------------------------------------------------------------------------------------------------

    # BNEP_TYPE=0x03 BNEP_COMPRESSED_ETHERNET_SOURCE_ONLY
    COMPRESSED_ETHERNET_SOURCE_ONLY_SOURCE_ADDRESS = [] # 48bits
    COMPRESSED_ETHERNET_SOURCE_ONLY_NETWORKING_PROTOCOL_TYPE = [] # 16bits

    # --------------------------------------------------------------------------------------------------------

    # BNEP_TYPE=0x04 BNEP_COMPRESSED_ETHERNET_DEST_ONLY
    COMPRESSED_ETHERNET_DEST_ONLY_DESTINATION_ADDRESS = [] # 48bits
    COMPRESSED_ETHERNET_DEST_ONLY_NETWORKING_PROTOCOL_TYPE = [] # 16bits

    # --------------------------------------------------------------------------------------------------------

    # Extension Header = Extension type(7 bits) + E(1 bit) + Extension Length(1 byte) + Extension Payload
    EXTENSION_TYPE = [] # BNEP_EXTENSION_CONTROL 0x00

    # --------------------------------------------------------------------------------------------------------
    def __init__(self, addr):
        self.addr = addr

    def send_bnep(self, msg):
        psm = 15
        sock = bluetooth.BluetoothSocket(bluetooth.L2CAP)
        sock.settimeout(5)
        try:
            sock.connect((self.addr, psm))
        except:
            return 1
        try:
            # 同一个包发5次
            for i in range(0, 5):
                sock.send(msg)
        except:
            return 2
        return 0

    # no EXTENSION BNEP_TYPE=0x00 BNEP_GENERAL_ETHERNET
    # 调用一次为一次fuzz测试
    def fuzz_bnep_general_ethernet(self):
        bnep_type = '\x00'
        destination_address = '\x00\x30\xB7\x45\x67\x89'
        source_address = '\x00\xAA\x00\x55\x44\x33'
        network_protocol_type = '\x80\x00'
        playload = '\x81' * 5
        r_code = random.randint(0, 3)
        rand = random.Random()
        r_flag = random.randint(1, 12)
        if r_code == 0:
            destination_address = self._fs(destination_address, rand, r_flag)
        if r_code == 1:
            source_address = self._fs(source_address, rand, r_flag)
        if r_code == 2:
            network_protocol_type = self._fs(network_protocol_type, rand, r_flag)
        if r_code == 3:
            playload = self._fs(playload, rand, r_flag)
        msg = bnep_type + destination_address + source_address + network_protocol_type + playload
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_code, r_flag, msg, bnep_type, destination_address, source_address, network_protocol_type, playload]

    # EXTENSION=1 BNEP_TYPE=0x00 BNEP_GENERAL_ETHERNET
    # 调用一次为一次fuzz测试
    def fuzz_bnep_general_ethernet_with_e(self):
        bnep_type_with_e = '\x80'
        destination_address = '\x00\x30\xB7\x45\x67\x89'
        source_address = '\x00\xAA\x00\x55\x44\x33'
        network_protocol_type = '\x80\x00'
        playload = '\x81' * 5
        extension_type = '\x00'
        extension_playload = '\x80' * 10
        rand = random.Random()
        r_flag = random.randint(1, 12)
        extension_playload = self._fs(extension_playload, rand, r_flag)
        msg = bnep_type_with_e + destination_address + source_address + network_protocol_type + playload + extension_type + extension_playload
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        #return [network_code, r_flag, msg, bnep_type_with_e, destination_address, source_address,
                #network_protocol_type, playload, extension_type, extension_playload]


    # no EXTENSION BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD 00
    def fuzz_bnep_control0(self):
        bnep_type = '\x01'
        bnep_control_type = '\x00' # BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD
        unkonwn_control_type = '\x81' * 5
        rand = random.Random()
        r_flag = random.randint(1, 12)
        unkonwn_control_type = self._fs(unkonwn_control_type, rand, r_flag)
        msg = bnep_type + bnep_control_type + unkonwn_control_type
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, bnep_control_type, unkonwn_control_type]

    # EXTENSION=1 BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD 00
    def fuzz_bnep_control0_with_e(self):
        bnep_type = '\x81'
        bnep_control_type = '\x00'  # BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD
        unkonwn_control_type = '\x81' * 5
        rand = random.Random()
        r_flag = random.randint(1, 12)
        extension_type = '\x00'
        extension_playload = '\x80' * 10
        extension_playload = self._fs(extension_playload, rand, r_flag)
        msg = bnep_type + bnep_control_type + unkonwn_control_type + extension_type + extension_playload
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, bnep_control_type, unkonwn_control_type, extension_type, extension_playload]

    # no EXTENSION BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_SETUP_CONNECTION_REQUEST_MSG 01
    def fuzz_bnep_control1(self):
        bnep_type = '\x01'
        bnep_control_type = '\x01' # BNEP_SETUP_CONNECTION_REQUEST_MSG
        uuid_size = '\x10'
        destination_service_uuid = '\x00\x00\x11\x16\x00\x00\x10\x00\x80\x00\x00\x80\x5F\x9B\x34\xFB'
        source_service_uuid = '\x00\x00\x11\x15\x00\x00\x10\x00\x80\x00\x00\x80\x5F\x9B\x34\xFB'
        rand = random.Random()
        r_code = random.randint(0, 2)
        r_flag = random.randint(1, 12)
        # fuzz  destination_service_uuid or source_service_uuid or uuid_size
        if r_code == 0:
            uuid_size = self._fs(uuid_size, rand, r_flag)
        if r_code == 1:
            destination_service_uuid = self._fs(destination_service_uuid, rand, r_flag)
        if r_code == 2:
            source_service_uuid = self._fs(source_service_uuid, rand, r_flag)
        msg = bnep_type + bnep_control_type + uuid_size + destination_service_uuid + source_service_uuid
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_code, r_flag, msg, bnep_type, bnep_control_type, uuid_size, destination_service_uuid, source_service_uuid]

    # EXTENSION=1 BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_SETUP_CONNECTION_REQUEST_MSG 01
    def fuzz_bnep_control1_with_e(self):
        bnep_type = '\x81'
        bnep_control_type = '\x01'  # BNEP_SETUP_CONNECTION_REQUEST_MSG
        uuid_size = '\x10'
        destination_service_uuid = '\x00\x00\x11\x16\x00\x00\x10\x00\x80\x00\x00\x80\x5F\x9B\x34\xFB'
        source_service_uuid = '\x00\x00\x11\x15\x00\x00\x10\x00\x80\x00\x00\x80\x5F\x9B\x34\xFB'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        extension_type = '\x00'
        extension_playload = '\x80' * 10
        extension_playload = self._fs(extension_playload, rand, r_flag)
        msg = bnep_type + bnep_control_type + uuid_size + destination_service_uuid + source_service_uuid + extension_type + extension_playload
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, bnep_control_type, uuid_size,
                #destination_service_uuid, source_service_uuid, extension_type, extension_playload]

    # no EXTENSION BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_SETUP_CONNECTION_RESPONSE_MSG 02
    def fuzz_bnep_control2(self):
        bnep_type = '\x01'
        bnep_control_type = '\x02' # BNEP_SETUP_CONNECTION_RESPONSE_MSG
        response_message = '\x00\x01'
        # fuzz response_message
        rand = random.Random()
        r_flag = random.randint(1, 12)
        response_message = self._fs(response_message, rand, r_flag)
        msg = bnep_type + bnep_control_type + response_message
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, bnep_control_type, response_message]

    # EXTENSION=1 BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_SETUP_CONNECTION_RESPONSE_MSG 02
    def fuzz_bnep_control2_with_e(self):
        bnep_type = '\x81'
        bnep_control_type = '\x02'  # BNEP_SETUP_CONNECTION_RESPONSE_MSG
        response_message = '\x00\x01'
        # fuzz response_message
        rand = random.Random()
        r_flag = random.randint(1, 12)
        extension_type = '\x00'
        extension_playload = '\x80' * 10
        extension_playload = self._fs(extension_playload, rand, r_flag)
        msg = bnep_type + bnep_control_type + response_message + extension_type + extension_playload
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, bnep_control_type, response_message, extension_type, extension_playload]

    # no EXTENSION BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_FILTER_NET_TYPE_SET_MSG 03
    '''
    BNEP_FILTER_NET_TYPE_SET_MSG
    FILTER_NET_TYPE_SET_MSG_LIST_LENGTH = []
    NETWORK_PROTOCOL_TYPE_START = []  # 16bits
    NETWORK_PROTOCOL_TYPE_END = []  # 16bits
    '''
    def fuzz_bnep_control3(self):
        bnep_type = '\x01'
        bnep_control_type = '\x03'
        list_length = '\x00\x04'
        network_protocol_type_start = '\x86\xDD'
        network_protocol_type_end = '\x86\xDD'
        rand = random.Random()
        r_code = random.randint(0, 2)
        r_flag = random.randint(1, 12)
        if r_code == 0:
            list_length = self._fs(list_length, rand, r_flag)
        if r_code == 1:
            network_protocol_type_start = self._fs(network_protocol_type_start, rand, r_flag)
        if r_code == 2:
            network_protocol_type_end = self._fs(network_protocol_type_end, rand, r_flag)
        msg = bnep_type + bnep_control_type + list_length + network_protocol_type_start + network_protocol_type_end
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        #return [network_code, r_code, r_flag, msg, bnep_type, bnep_control_type, list_length, network_protocol_type_start,
                #network_protocol_type_end]

    # EXTENSION=1 BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_FILTER_NET_TYPE_SET_MSG 03
    def fuzz_bnep_control3_with_e(self):
        bnep_type = '\x81'
        bnep_control_type = '\x03'
        list_length = '\x00\x04'
        network_protocol_type_start = '\x86\xDD'
        network_protocol_type_end = '\x86\xDD'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        extension_type = '\x00'
        extension_playload = '\x80' * 10
        extension_playload = self._fs(extension_playload, rand, r_flag)
        msg = bnep_type + bnep_control_type + list_length + network_protocol_type_start + network_protocol_type_end + extension_type + extension_playload
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        #return [network_code, r_flag, msg, bnep_type, bnep_control_type, list_length, network_protocol_type_start,
               # network_protocol_type_end, extension_type, extension_playload]

    # no EXTENSION BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_SETUP_CONNECTION_RESPONSE_MSG 04
    def fuzz_bnep_control4(self):
        bnep_type = '\x01'
        bnep_control_type = '\x04'
        response_message = '\x00\x01'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        response_message = self._fs(response_message, rand, r_flag)
        msg = bnep_type + bnep_control_type + response_message
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, bnep_control_type, response_message]

    # EXTENSION=1 BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_SETUP_CONNECTION_RESPONSE_MSG 04
    def fuzz_bnep_control4_with_e(self):
        bnep_type = '\x81'
        bnep_control_type = '\x04'
        response_message = '\x00\x01'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        extension_type = '\x00'
        extension_playload = '\x80' * 10
        extension_playload = self._fs(extension_playload, rand, r_flag)
        msg = bnep_type + bnep_control_type + response_message + extension_type + extension_playload
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, bnep_control_type, response_message, extension_type, extension_playload]

    # no EXTENSION BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_FILTER_MULTI_ADDR_SET_MSG 05
    def fuzz_bnep_control5(self):
        bnep_type = '\x01'
        bnep_control_type = '\x05'
        list_length = '\x00\x0C'
        multicast_address_start = '\x01\x00\x5E\x20\x00\x00'
        multicast_address_end = '\x01\x00\x5E\x20\x00\x00'
        rand = random.Random()
        r_code = random.randint(0, 2)
        r_flag = random.randint(1, 12)
        if r_code == 0:
            list_length = self._fs(list_length, rand, r_flag)
        if r_code == 1:
            multicast_address_start = self._fs(multicast_address_start, rand, r_flag)
        if r_code == 2:
            multicast_address_end = self._fs(multicast_address_end, rand, r_flag)
        msg = bnep_type + bnep_control_type + list_length + multicast_address_start + multicast_address_end
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_code, r_flag, msg, bnep_type, bnep_control_type, list_length, multicast_address_start, multicast_address_end]

    # EXTENSION=1 BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_FILTER_MULTI_ADDR_SET_MSG 05
    def fuzz_bnep_control5_with_e(self):
        bnep_type = '\x81'
        bnep_control_type = '\x05'
        list_length = '\x00\x0C'
        multicast_address_start = '\x01\x00\x5E\x20\x00\x00'
        multicast_address_end = '\x01\x00\x5E\x20\x00\x00'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        extension_type = '\x00'
        extension_playload = '\x80' * 10
        extension_playload = self._fs(extension_playload, rand, r_flag)
        msg = bnep_type + bnep_control_type + list_length + multicast_address_start + multicast_address_end + extension_type, extension_playload
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, bnep_control_type, list_length, multicast_address_start, multicast_address_end, extension_type, extension_playload]

    # no EXTENSION BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG 06
    def fuzz_bnep_control6(self):
        bnep_type = '\x01'
        bnep_control_type = '\x06'
        response_message = '\x00\x01'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        response_message = self._fs(response_message, rand, r_flag)
        msg = bnep_type + bnep_control_type + response_message
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, bnep_control_type, response_message]

    # EXTENSION=1 BNEP_TYPE=0x01 BNEP_CONTROL BNEP Control Type=BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG 06
    def fuzz_bnep_control6_with_e(self):
        bnep_type = '\x81'
        bnep_control_type = '\x06'
        response_message = '\x00\x01'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        extension_type = '\x00'
        extension_playload = '\x80' * 10
        extension_playload = self._fs(extension_playload, rand, r_flag)
        msg = bnep_type + bnep_control_type + response_message + extension_type + extension_playload
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, bnep_control_type, response_message, extension_type, extension_playload]

    # no EXTENSION fuzz bnep_control_type
    def fuzz_bnep_control(self):
        bnep_type = '\x01'
        bnep_control_type = '\x07'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        bnep_control_type = self._fs(bnep_control_type, rand, r_flag)
        msg = bnep_type + bnep_control_type
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, bnep_control_type]

    # EXTENSION=1 fuzz bnep_control_type
    def fuzz_bnep_control_with_e(self):
        bnep_type = '\x81'
        bnep_control_type = '\x07'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        extension_type = '\x00'
        extension_playload = '\x80' * 10
        extension_playload = self._fs(extension_playload, rand, r_flag)
        msg = bnep_type + bnep_control_type + extension_type + extension_playload
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, bnep_control_type, extension_type, extension_playload]


    # no EXTENSION fuzz BNEP_COMPRESSED_ETHERNET    bnep_type=02
    def fuzz_bnep_compressed_ethernet(self):
        bnep_type = '\x02'
        networking_protocol_type = '\x80\x01'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        networking_protocol_type = self._fs(networking_protocol_type, rand, r_flag)
        msg = bnep_type + networking_protocol_type
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, networking_protocol_type]

    # EXTENSION=1 fuzz BNEP_COMPRESSED_ETHERNET    bnep_type=02
    def fuzz_bnep_compressed_ethernet_with_e(self):
        bnep_type = '\x82'
        networking_protocol_type = '\x80\x01'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        extension_type = '\x00'
        extension_playload = '\x80' * 10
        extension_playload = self._fs(extension_playload, rand, r_flag)
        msg = bnep_type + networking_protocol_type + extension_type + extension_playload
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, networking_protocol_type, extension_type, extension_playload]

    # no EXTENSION fuzz BNEP_COMPRESSED_ETHERNET_SOURCE_ONLY  bnep_type=03
    # COMPRESSED_ETHERNET_SOURCE_ONLY_SOURCE_ADDRESS = [] # 48bits
    # COMPRESSED_ETHERNET_SOURCE_ONLY_NETWORKING_PROTOCOL_TYPE = [] # 16bits
    def fuzz_bnep_compressed_ethernet_source_only(self):
        bnep_type = '\x03'
        compressed_ethernet_source_only_source_address = '\x80\x01\x02\x03\x08\xFF'
        compressed_ethernet_source_only_networking_protocol_type = '\x81\x80'
        rand = random.Random()
        r_code = random.randint(0, 1)
        r_flag = random.randint(1, 12)
        if r_code == 0:
            compressed_ethernet_source_only_source_address = self._fs(compressed_ethernet_source_only_source_address, rand, r_flag)
        if r_code == 1:
            compressed_ethernet_source_only_networking_protocol_type = self._fs(compressed_ethernet_source_only_networking_protocol_type, rand, r_flag)
        msg = bnep_type + compressed_ethernet_source_only_source_address + compressed_ethernet_source_only_networking_protocol_type
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_code, r_flag, msg, bnep_type, compressed_ethernet_source_only_source_address, compressed_ethernet_source_only_networking_protocol_type]

    # EXTENSION=1 fuzz BNEP_COMPRESSED_ETHERNET_SOURCE_ONLY  bnep_type=03
    def fuzz_bnep_compressed_ethernet_source_only_with_e(self):
        bnep_type = '\x83'
        compressed_ethernet_source_only_source_address = '\x80\x01\x02\x03\x08\xFF'
        compressed_ethernet_source_only_networking_protocol_type = '\x81\x80'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        extension_type = '\x00'
        extension_playload = '\x80' * 10
        extension_playload = self._fs(extension_playload, rand, r_flag)
        msg = bnep_type + compressed_ethernet_source_only_source_address + compressed_ethernet_source_only_networking_protocol_type + extension_type + extension_playload
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, compressed_ethernet_source_only_source_address,
                #compressed_ethernet_source_only_networking_protocol_type, extension_type, extension_playload]

    # no EXTENSION fuzz BNEP_COMPRESSED_ETHERNET_DEST_ONLY  bnep_type=04
    # COMPRESSED_ETHERNET_DEST_ONLY_DESTINATION_ADDRESS = []  # 48bits
    # COMPRESSED_ETHERNET_DEST_ONLY_NETWORKING_PROTOCOL_TYPE = []  # 16bits
    def fuzz_bnep_compressed_ethernet_dest_only(self):
        bnep_type = '\x04'
        compressed_ethernet_dest_only_destination_address = '\x80\x01\x02\x03\x08\xFF'
        compressed_ethernet_dest_only_networking_protocol_type = '\x80\x81'
        rand = random.Random()
        r_code = random.randint(0, 1)
        r_flag = random.randint(1, 12)
        if r_code == 0:
            compressed_ethernet_dest_only_destination_address = self._fs(compressed_ethernet_dest_only_destination_address, rand, r_flag)
        if r_code == 1:
            compressed_ethernet_dest_only_networking_protocol_type = self._fs(compressed_ethernet_dest_only_networking_protocol_type, rand, r_flag)
        msg = bnep_type + compressed_ethernet_dest_only_destination_address + compressed_ethernet_dest_only_networking_protocol_type
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, r_code, bnep_type, compressed_ethernet_dest_only_destination_address, compressed_ethernet_dest_only_networking_protocol_type]

    # EXTENSION=1 fuzz BNEP_COMPRESSED_ETHERNET_DEST_ONLY  bnep_type=04
    def fuzz_bnep_compressed_ethernet_dest_only_with_e(self):
        bnep_type = '\x84'
        compressed_ethernet_dest_only_destination_address = '\x80\x01\x02\x03\x08\xFF'
        compressed_ethernet_dest_only_networking_protocol_type = '\x80\x81'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        extension_type = '\x00'
        extension_playload = '\x80' * 10
        extension_playload = self._fs(extension_playload, rand, r_flag)
        msg = bnep_type + compressed_ethernet_dest_only_destination_address + compressed_ethernet_dest_only_networking_protocol_type
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg]
        # return [network_code, r_flag, msg, bnep_type, compressed_ethernet_dest_only_destination_address, compressed_ethernet_dest_only_networking_protocol_type, extension_type, extension_playload]

    # fuzz bnep_type
    def fuzz_bnep_type(self):
        bnep_type = '\x0F'
        rand = random.Random()
        r_flag = random.randint(1, 12)
        bnep_type = self._fs(bnep_type, rand, r_flag)
        msg = bnep_type
        network_code = self.send_bnep(msg)
        return [network_code, r_flag, msg, bnep_type]


    def bnep_random_fuzz(self):
        i = random.randint(0, 23)
        if i == 0:
            return self.fuzz_bnep_control4_with_e()
        if i == 1:
            return self.fuzz_bnep_control()
        if i == 2:
            return self.fuzz_bnep_control4()
        if i == 3:
            return self.fuzz_bnep_control3_with_e()
        if i == 4:
            return self.fuzz_bnep_control3()
        if i == 5:
            return self.fuzz_bnep_control2_with_e()
        if i == 6:
            return self.fuzz_bnep_control2()
        if i == 7:
            return self.fuzz_bnep_control1_with_e()
        if i == 8:
            return self.fuzz_bnep_control1()
        if i == 9:
            return self.fuzz_bnep_control0_with_e()
        if i == 10:
            return self.fuzz_bnep_control0()
        if i == 11:
            return self.fuzz_bnep_general_ethernet_with_e()
        if i == 12:
            return self.fuzz_bnep_general_ethernet()
        if i == 13:
            return self.fuzz_bnep_compressed_ethernet()
        if i == 14:
            return self.fuzz_bnep_compressed_ethernet_dest_only()
        if i == 15:
            return self.fuzz_bnep_compressed_ethernet_source_only()
        if i == 16:
            return self.fuzz_bnep_compressed_ethernet_source_only_with_e()
        if i == 17:
            return self.fuzz_bnep_compressed_ethernet_with_e()
        if i == 18:
            return self.fuzz_bnep_type()
        if i == 19:
            return self.fuzz_bnep_compressed_ethernet_dest_only_with_e()
        if i == 20:
            return self.fuzz_bnep_control5()
        if i == 21:
            return self.fuzz_bnep_control5_with_e()
        if i == 22:
            return self.fuzz_bnep_control6()
        if i == 23:
            return self.fuzz_bnep_control6_with_e()

    def _fs(self, data, rand, flag):

        if (flag == 0):
            return data

        if (flag == 1):
            s = stringmuta.StringCaseMutator()
            return s.mutationRandomCase(data)

        if (flag == 2):
            s = stringmuta.UnicodeBomMutator()
            return s.randomMutation(rand)

        if (flag == 3):
            s = stringmuta.UnicodeBadUtf8Mutator()
            return s.randomMutation(rand)

        if (flag == 4):
            b = blobmuta.DWORDSliderMutator(data)
            return b.randomMutation(data, rand)

        if (flag == 5):
            b = blobmuta.BitFlipperMutator(data)
            return b.randomMutation(data, rand)

        b = blobmuta.BlobMutator(data)
        if (flag == 6):
            return ""  # 返回空字符串

        if (flag == 7):
            return b.changeReduceBuffer(data, rand)

        if (flag == 8):
            return b.changeChangeRangeSpecial(data, rand)

        if (flag == 9):
            return b.changeExpandBuffer(data, rand)

        if (flag == 10):
            return b.changeNullRange(data, rand)

        if (flag == 11):
            return b.changeChangeRange(data, rand)

        if (flag == 12):
            h = binarymuta.Handler()
            return h.Fuzzit(data)




# 3C:F5:91:3F:24:04 OPPO R11
# D8:32:E3:A6:A3:74 红米手机

if __name__ == '__main__':
    addr = 'D8:32:E3:A6:A3:74'
    b = Bnep(addr)
    for i in range(0, 20):
        print b.fuzz_bnep_control5()